Generic Migrations in Fluent
So we pre-populated our database with initial data in previous two tips and even added related data. That’s fine, but it is all related to #postgresql.
What if we wanted to make it work with all the databases that Vapor
supports.
Well in that case we need a Generic Migration
.
import Async
import Fluent
import Foundation
public final class TestModel<D>: Model where D: QuerySupporting {
public typealias Database = D
public typealias ID = Int
public static var idKey: IDKey { return \.id }
public static var entity: String {
return "testModel"
}
public static var database: DatabaseIdentifier<D> {
return .init("test")
}
var id: Int?
var name: String
var num : Int
init(name: String, num: Int) {
self.name = name
self.num = num
}
}
extension TestModel: Migration where D: SchemaSupporting, D: QuerySupporting { }
extension MigrationConfig {
public mutating func addTestModels<D>(for database: DatabaseIdentifier<D>)
where D: QuerySupporting, D: IndexSupporting {
self.add(model: TestModel<D>.self, database: database)
}
}
let testNames = [
"test_Name_1",
"test_Name_2",
"test_Name_3"
]
internal struct TestModelMigration<D>: Migration where D: QuerySupporting & SchemaSupporting {
typealias Database = D
static func prepare(on connection: Database.Connection) -> Future<Void> {
//Insert all names
let futures : [EventLoopFuture<Void>] = testNames.map { name in
return TestModel<D>(name: name, num: 1).create(on: connection).map(to: Void.self) { _ in return }
}
return Future<Void>.andAll(futures, eventLoop: connection.eventLoop)
}
static func revert(on connection: Database.Connection) -> Future<Void> {
do {
// Delete all names
let futures = try testNames.map { name in
return try TestModel<D>.query(on: connection).filter(\TestModel.name, .equals, .data(name)).delete()
}
return Future<Void>.andAll(futures, eventLoop: connection.eventLoop)
}
catch {
return connection.eventLoop.newFailedFuture(error: error)
}
}
}
Run your migration
In configure.swift
add the code:
migrations.add(model: TestModel<PostgreSQLDatabase>.self, database: .psql)
migrations.add(migration: TestModelMigration<PostgreSQLDatabase>.self, database: .psql)
And the data is added:
Prev: Pre-populating Related Tables in Vapor
Next: Generic Pre-populated Models in Fluent
#tutorial #fluent #vapor #model #migration #db #generic #pub #pre-populate